package com.xiaochen.autohttpinvoker;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.core.type.filter.AnnotationTypeFilter;
import org.springframework.remoting.httpinvoker.HttpInvokerProxyFactoryBean;
import org.springframework.util.ClassUtils;

import java.util.Set;
/**
*  扫描被RpcConsumer注解的类
* @author chenkangyong
* @date 2019/3/19 9:54
*/
@Slf4j
public class RpcConsumerScanner implements BeanDefinitionRegistryPostProcessor, EnvironmentAware {
    private Environment environment;
    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        String remotePrefix= environment.resolvePlaceholders("${rpc.consumer.baseUrl}");
        String basePackage= environment.resolvePlaceholders("${rpc.consumer.basePackage}");
        HttpInvokerScanner beanScanner = new HttpInvokerScanner(false);
        beanScanner.addIncludeFilter(new AnnotationTypeFilter(RpcConsumer.class));
        long startTime = System.currentTimeMillis();
        Set<BeanDefinition> beanDefinitions = beanScanner.findCandidateComponents(basePackage);
        log.info("扫描含有RpcConsumer注解的接口共用[{}]个", beanDefinitions.size());
        for (BeanDefinition beanDefinition : beanDefinitions) {
            try {
                if(null==beanDefinition.getBeanClassName()){
                    continue;
                }
                Class<?> interfaceClass = ClassUtils.forName(beanDefinition.getBeanClassName(), this.getClass().getClassLoader());
                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(HttpInvokerProxyFactoryBean.class);
                String simpleClassName = interfaceClass.getSimpleName();
                String url = remotePrefix + simpleClassName.substring(0, 1).toLowerCase() + simpleClassName.substring(1);
                builder.addPropertyValue("serviceUrl", url);
                builder.addPropertyValue("serviceInterface", interfaceClass);
                BeanDefinition register = builder.getRawBeanDefinition();
                beanDefinitionRegistry.registerBeanDefinition("proxy"+simpleClassName, register);
                log.info("----注册消费者[{}]，路径为[{}]----",simpleClassName, url);
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        log.info("扫描共花费了[{}ms]", System.currentTimeMillis() - startTime);
    }
    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {
    }

    @Override
    public void setEnvironment(Environment environment) {
        this.environment= environment;
    }
}
